package com.jokins.common.util.date;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 〈〉<br>
 *
 * @author Mr.Wang
 * @create 2025/2/5
 */
public class UniqueNumberGenerator {
    // 核心配置参数
    private static final int POOL_SIZE = 100;
    private static final int REFILL_THRESHOLD = 20;
    private static final int MAX_RETRY = 5000;

    // 存储系统
    private static final Set<String> generatedNumbers = ConcurrentHashMap.newKeySet();
    private static final Queue<String> numberPool = new LinkedList<>();

    // 特殊号码配置
    private static final Set<String> forbiddenNumbers = new HashSet<>(Arrays.asList(
            "12345678", "88888888", "00000000"
    ));

    private static final Map<String, String> popularNumbers = new ConcurrentHashMap<>() {{
        put("VIP1", "13145200");
        put("LUCKY2", "66886688");
        put("DATE3", "20240808");
    }};

    /**
     * 生成唯一号码（主入口）
     */
    public static synchronized String generate() {
        if (numberPool.size() < REFILL_THRESHOLD) {
            refillPool(POOL_SIZE - numberPool.size());
        }
        return numberPool.poll();
    }

    /**
     * 智能补充号码池
     * @param required 需要补充的数量
     */
    private static void refillPool(int required) {
        List<String> candidates = new ArrayList<>(required);
        int generated = 0;
        int retryCount = 0;

        while (generated < required && retryCount < MAX_RETRY) {
            String candidate = generateCandidate();
            if (isValidNumber(candidate)) {
                candidates.add(candidate);
                generated++;
                generatedNumbers.add(candidate);
            }
            retryCount++;
        }

        if (candidates.isEmpty()) {
            throw new IllegalStateException("无法生成有效号码，请检查限制规则");
        }

        Collections.shuffle(candidates);
        numberPool.addAll(candidates);
    }

    /**
     * 生成候选号码（基础算法）
     */
    private static String generateCandidate() {
        List<Integer> digits = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) digits.add(i);
        Collections.shuffle(digits);

        return digits.subList(0, 8).stream()
                .map(String::valueOf)
                .collect(Collectors.joining());
    }

    /**
     * 增强校验逻辑
     */
    private static boolean isValidNumber(String number) {
        return !generatedNumbers.contains(number)
                && !forbiddenNumbers.contains(number)
                && !popularNumbers.containsValue(number)
                && number.chars().distinct().count() == 8;
    }

    /**
     * 获取指定流行号码
     * @param key 流行号码键
     * @return 对应的号码，不存在返回null
     */
    public static String getPopularNumber(String key) {
        return popularNumbers.get(key);
    }

    /**
     * 随机获取一个流行号码
     */
    public static String getRandomPopularNumber() {
        if (popularNumbers.isEmpty()) return null;
        List<String> numbers = new ArrayList<>(popularNumbers.values());
        Collections.shuffle(numbers);
        return numbers.get(0);
    }

    public static void main(String[] args) {
        // 测试生成
        System.out.println("随机生成：" + generate());
        System.out.println("指定获取：" + getPopularNumber("VIP1"));
        System.out.println("随机流行：" + getRandomPopularNumber());

        // 压力测试
        for (int i = 0; i < 5; i++) {
            System.out.println("生成号码#" + i + ": " + generate());
        }
    }
}